package com.way.flow

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.zip
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.supervisorScope
import org.junit.Test

import org.junit.Assert.*

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * See [testing documentation](http://d.android.com/tools/testing).
 */
class ExampleUnitTest {

    @Test
    fun addition_isCorrect() {
        assertEquals(4, 2 + 2)
    }

    @Test
    fun testMultipleValues() = runBlocking<Unit> {
        simpleList().collect { v -> println(v) }
        launch {
            for (i in 1..5){
                delay(1000)
                println("I am watching TV")
            }
        }

        println("end of test fun")
    }

    private suspend fun simpleList()= flow<Int>{
        for (i in 1..3){
            delay(1000)
            emit(i)
        }
    }

    @Test
    fun test_zip () = runBlocking<Unit>{
        val numbers = (1..3).asFlow().onEach { delay(300) }
        val strs = flowOf("one", "two", "three").onEach { delay(400) }
        var st = System.currentTimeMillis()
        numbers.zip(strs){
            a,b->"$a -> $b"
        }.collect{
            println("$it at ${System.currentTimeMillis() - st} ms from start")
        }
    }

    @Test
    fun test_fs(): Unit = runBlocking {
        val job = GlobalScope.launch {
            CoroutineScope(Dispatchers.IO).launch {
                delay(1000)
                println("coroutine IO")
            }

            CoroutineScope(coroutineContext).launch{
                delay(500)
                println("coroutineContext")
            }

            CoroutineScope(coroutineContext+ Job()).launch {
                delay(600)
                println("coroutineContext+job")
            }
            println("global scope")
        }
        job.join()
    }

    @Test
    fun test_MainScope() = runBlocking<Unit> {


        println("word from globalScope")
    }

}